/**
 * Created by xiongwei on 2017/3/15.
 */
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {Dimensions, StyleSheet, Text, TouchableOpacity, View,} from 'react-native';
import moment from 'moment';
import AppConfig from '@constants/config';
import {AppColors, AppStyles} from '@theme/';

const DEVICE_WIDTH = Dimensions.get('window').width;
const grid = 4;

const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: 'white',
    width: DEVICE_WIDTH,
  },
  calendarHeader: {
    paddingVertical: 5,
    alignItems: 'center',
    flexDirection: 'row',
  },
  workDayHeader: {
    flex: 1,
    fontSize: 16,
    color: AppColors.colors.grey2,
    margin: 3,
    textAlign: 'center',
  },
  weekendHeader: {
    flex: 1,
    fontSize: 16,
    color: AppColors.colors.grey1,
    margin: 3,
    textAlign: 'center',
  },
  workDayText: {
    fontSize: 16,
    fontWeight: '500',
    color: AppColors.colors.grey1,
    textAlign: 'center',
    backgroundColor: AppColors.transparent,
  },
  weekendText: {
    fontSize: 16,
    color: AppColors.colors.grey1,
    textAlign: 'center',
  },
  todayText: {
    fontSize: 16,
    color: 'white',
    textAlign: 'center',
  },
  diffMonthDayText: {
    fontSize: 16,
    color: AppColors.colors.grey4,
    margin: 3,
    textAlign: 'center',
  },
  calendarRow: {
    flex: 1,
    alignItems: 'center',
    flexDirection: 'row',
    borderBottomColor: AppColors.divider,
    borderBottomWidth: 1,
    backgroundColor: '#fff',
  },
  calendarDayText: {},
  calendarDayBg: {
    justifyContent: 'center',
    alignItems: 'center',
  },

  dot: {
    borderRadius: grid,
    backgroundColor: 'yellow',
    position: 'absolute',
    bottom: 0,
    right: 0,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 4,
  },
});

/**
 * 日历 可定制
 */
export default class Calendar extends Component {

  static propTypes = {
    date: PropTypes.object,
    displayMode: PropTypes.oneOf(['month', 'week']),
    width: PropTypes.number,
    weekHeaders: PropTypes.array,
    weekStart: PropTypes.number,
    customStyle: PropTypes.object,
    onDateSelected: PropTypes.func,
    events: PropTypes.object,
    // 自定义绘制星期 参数:index, weekIndex，  index 代表第几列，  weekIndex代表星期序列0：代表星期一
    drawWeek: PropTypes.func,
    // 自定义绘制日期 参数index 第几列， day moment对象, isSameMonth 是否是同一个月, isWeekendDay 是否双休, isToday 是否是当天
    drawDay: PropTypes.func,
  };

  static defaultProps = {
    date: new Date(),
    displayMode: 'month',
    width: DEVICE_WIDTH,
    weekHeaders: ['一', '二', '三', '四', '五', '六', '日'],
    weekStart: 0,
    customStyle: {
      margin: 0,
    },
    onDateSelected: () => {
    },
    events: {},
  };

  constructor(props) {
    super(props);
    const {date} = this.props;
    this.state = {
      currentMonth: moment(date),
    };
  }

  _renderWeekHeaders = () => {

    const {drawWeek} = this.props;
    const headers = [];
    for (let i = 0; i < this.props.weekHeaders.length; i += 1) {
      const j = (i + this.props.weekStart) % this.props.weekHeaders.length;
      headers.push(
        this.getWeekView(i, j)
      );
    }
    return (
      <View style={[styles.calendarHeader, this.props.customStyle.calendarHeader]}>
        {headers}
      </View>
    );
  };

  getWeekView = (index, weekIndex) => {
    const {drawWeek} = this.props;
    return !!drawWeek ? drawWeek(index, weekIndex) : (
      <Text
        key={index}
        style={weekIndex >= 5 ? [styles.weekendHeader, this.props.customStyle.weekendHeader] :
          [styles.workDayHeader, this.props.customStyle.workDayHeader]}
      >
        {this.props.weekHeaders[weekIndex]}
      </Text>);
  }

  _renderMonthDays = () => {
    const {displayMode, date, weekStart} = this.props;
    const currentMonth = moment(date);
    const startOfMonth = moment(currentMonth).startOf('month');
    const offset = (startOfMonth.isoWeekday() - 1 - weekStart + 7) % 7;
    const daysInMonth = currentMonth.daysInMonth(); // 在月份里是几号
    const numOfWeeks = (offset + daysInMonth) % 7 === 0 ? (offset + daysInMonth) / 7 : Math.ceil((offset + daysInMonth) / 7);
    const rows = [];

    // 背景图片的宽高
    // const width = DEVICE_WIDTH / 7 - 10;
    // const height = width;
    for (let i = -offset; i < numOfWeeks * 7 - offset; i += 7) {
      const days = [];
      let currentWeek = false;
      for (let j = 0; j < 7; j += 1) {
        const day = moment(startOfMonth).add(i + j, 'days');
        const isSameMonth = day.isSame(currentMonth, 'month');
        const isWeekendDay = day.isoWeekday() > 5;
        const isToday = day.isSame(currentMonth, 'day');
        if (isToday) {
          currentWeek = true;
        }
        days.push(
          this.getDayView(j, day, isSameMonth, isWeekendDay, isToday)
        );
      }
      if (displayMode !== 'week' || currentWeek) {
        rows.push(<View key={i + 7} style={[styles.calendarRow, this.props.customStyle.calendarRow]}>{days}</View>);
      }
    }
    return rows;
  };

  getDayView = (index, day, isSameMonth, isWeekendDay, isToday) => {

    const {customStyle, onDateSelected, events} = this.props;

    const width = 30;
    const height = 30;
    const event = events[day.format(AppConfig.FORMATS.DATE)];
    const isCurrentDay = day.isSame(currentDay, 'day');
    const currentDay = moment();

    return !!this.props.drawDay ? this.props.drawDay(index, day, isSameMonth, isWeekendDay, isToday) :
      (
        <TouchableOpacity
          key={index}
          style={{flex: 1, padding: 5, justifyContent: 'center', alignItems: 'center'}}
          activeOpacity={isSameMonth ? 0.8 : 1.0}
          onPress={() => isSameMonth && onDateSelected && onDateSelected(day.toDate(), event)}
        >
          <View
            style={[
              styles.calendarDayBg,
              {width, height},
              event && {backgroundColor: '#E7E7E7', borderRadius: height / 2},
              isCurrentDay && {backgroundColor: '#FC6D59', borderRadius: height / 2},
              isToday && {backgroundColor: '#FDC84A', borderRadius: height / 2},
            ]}
          >
            <Text
              style={[
                styles.workDayText,
                customStyle.workDayText,
                !isSameMonth && styles.diffMonthDayText,
                isSameMonth && isWeekendDay && styles.weekendText,
                (isToday || isCurrentDay) && styles.todayText,
                event && customStyle.eventDayText,
              ]}
            >
              {day.format('D')}
            </Text>
          </View>
          <View style={styles.dot}>
            <Text style={{fontSize: 10}}>6</Text>
          </View>
        </TouchableOpacity>
      );
  }

  render() {
    return (
      <View style={[styles.wrapper, this.props.customStyle.wrapper]}>
        {this._renderWeekHeaders()}
        {this._renderMonthDays()}
      </View>
    );
  }
}
